<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>向量数据库 - AI Chatroom</title>
    <style>
        * { margin: 0; padding: 0; box-sizing: border-box; }
        body { font-family: ui-sans-serif, system-ui, -apple-system, Segoe UI, Roboto, Helvetica, Arial; background: #0b0f19; color: #e5e7eb; }
        header { display:flex; justify-content: space-between; align-items:center; padding:12px 16px; border-bottom:1px solid #1f2937; background:#0f172a; }
        .btn { background:#111827; color:#e5e7eb; border:1px solid #1f2937; padding:8px 12px; border-radius:8px; cursor:pointer; }
        .btn.primary { background:#22c55e; color:#051b0d; font-weight:700; border-color:#16a34a; }
        .container { max-width: 1000px; margin: 0 auto; padding: 16px; }
        .card { background:#0f172a; border:1px solid #1f2937; border-radius:12px; padding:16px; margin-bottom: 16px; }
        .field { display:grid; gap:6px; margin:10px 0; }
        .input, .textarea { background:#0b1220; color:#e5e7eb; border:1px solid #1f2937; border-radius:8px; padding:10px 12px; }
        .textarea { min-height: 100px; resize: vertical; }
        .muted { color:#9ca3af; font-size:12px; }
        table { width:100%; border-collapse: collapse; }
        th, td { border-bottom:1px solid #1f2937; text-align:left; padding:8px; vertical-align: top; }
        .row { display:flex; gap:8px; }
        .table-wrap { overflow-x: auto; }
        @media (max-width: 600px) {
            header { flex-direction: column; align-items: flex-start; gap: 8px; }
            .container { padding: 12px; }
            .card { padding: 12px; }
            .input, .textarea { padding: 12px; font-size: 16px; width: 100%; }
            .row { flex-direction: column; }
            .btn { width: 100%; padding: 12px; font-size: 16px; }
            table { font-size: 14px; }
        }
    </style>
</head>
<body>
    <header>
        <div style="display:flex; align-items:center; gap:10px">
            <div style="width:10px;height:10px;border-radius:50%;background:#22c55e;box-shadow:0 0 10px #22c55e"></div>
            <strong>向量数据库</strong>
        </div>
        <div>
            <span class="muted" id="userInfo">未登录</span>
            <button class="btn" id="toLogin">登录</button>
            <a class="btn" href="index.html">聊天</a>
        </div>
    </header>

    <div class="container">
        <div class="card">
            <h3>新增文本到向量库</h3>
            <div class="field">
                <label class="muted">内容</label>
                <textarea id="addContent" class="textarea" placeholder="输入要向量化并存储的文本"></textarea>
            </div>
            <div class="row">
                <button id="btnAdd" class="btn primary">提交存储</button>
                <button id="btnDeleteMine" class="btn">删除我的向量</button>
            </div>
            <div class="muted" id="addMsg"></div>
        </div>

        <div class="card">
            <h3>相似度检索</h3>
            <div class="field">
                <label class="muted">查询文本</label>
                <input id="queryText" class="input" placeholder="输入想检索的内容">
            </div>
            <div class="row" style="margin-bottom:8px">
                <button id="btnSearch" class="btn primary">检索</button>
            </div>
            <div class="table-wrap">
            <table>
                <thead>
                    <tr><th style="width:40%">内容</th><th>元数据</th></tr>
                </thead>
                <tbody id="resultBody"></tbody>
            </table>
            </div>
        </div>
    </div>

    <script>
        function token(){ return localStorage.getItem('token') || ''; }
        // 统一按当前协议与主机直连 9091 端口，避免字符串替换带来的主机/端口错误
        const VECTOR_BASE = location.protocol + '//' + location.hostname + ':9090';
        function username(){ return localStorage.getItem('username') || ''; }
        function userId(){ return localStorage.getItem('userId') || ''; }
        function ensureLogin(){ if(!token()){ location.href = 'login.html?redirect=' + encodeURIComponent('vector.html'); return false; } return true; }
        function showUser(){ const u = username(); document.getElementById('userInfo').textContent = u ? ('账户：' + u) : '未登录'; document.getElementById('toLogin').style.display = u ? 'none' : ''; }

        // 导航
        document.getElementById('toLogin').addEventListener('click', ()=>{ location.href = 'login.html?redirect=' + encodeURIComponent('vector.html'); });

        // 受保护页面门禁
        if(!ensureLogin()) { /* 已跳转 */ }
        showUser();

        // 新增
        document.getElementById('btnAdd').addEventListener('click', async ()=>{
            if(!ensureLogin()) return;
            const content = document.getElementById('addContent').value.trim();
            const msg = document.getElementById('addMsg'); msg.textContent='';
            if(!content){ msg.textContent = '内容不能为空'; return; }
            try{
                // 使用表单方式放入请求体，避免超长 URL 失败
                const body = 'content=' + encodeURIComponent(content);
                const resp = await fetch(VECTOR_BASE + '/vector/store', { method:'POST', headers:{ 'token': token(), 'Content-Type': 'application/x-www-form-urlencoded' }, body });
                const text = await resp.text();
                let res; try { res = JSON.parse(text); } catch { res = null; }
                msg.textContent = (resp.ok && res && Number(res.code)===200) ? '存储成功' : (res && res.message ? res.message : ('存储失败：' + (text || ('HTTP ' + resp.status))));
                if(resp.ok && res && Number(res.code)===200){ document.getElementById('addContent').value=''; }
            }catch(e){ msg.textContent = '请求错误：' + e.message; }
        });

        // 删除我所有
        document.getElementById('btnDeleteMine').addEventListener('click', async ()=>{
            if(!ensureLogin()) return;
            if(!confirm('确定删除我账号下的所有向量？')) return;
            try{
                const resp = await fetch(VECTOR_BASE + '/vector/delete', { method:'DELETE', headers:{ 'token': token() } });
                const text = await resp.text();
                let res; try { res = JSON.parse(text); } catch { res = null; }
                alert((resp.ok && res && Number(res.code)===200) ? '删除成功' : (res && res.message ? res.message : ('删除失败：' + (text || ('HTTP ' + resp.status)))));
            }catch(e){ alert('请求错误：' + e.message); }
        });

        // 检索
        document.getElementById('btnSearch').addEventListener('click', async ()=>{
            if(!ensureLogin()) return;
            const q = document.getElementById('queryText').value.trim();
            const body = document.getElementById('resultBody'); body.innerHTML='';
            if(!q) return;
            try{
                const uid = userId();
                const resp = await fetch(VECTOR_BASE + '/vector/find?content=' + encodeURIComponent(q) + '&userId=' + encodeURIComponent(uid), { headers: { 'token': token() } });
                const text = await resp.text();
                let list; try { list = JSON.parse(text); } catch { list = []; }
                (Array.isArray(list) ? list : []).forEach(item=>{
                    const tr = document.createElement('tr');
                    const td1 = document.createElement('td');
                    const td2 = document.createElement('td');
                    // 兼容 Spring AI Document 命名
                    const content = item && (item.content || item.text || JSON.stringify(item));
                    const metadata = item && (item.metadata || item.meta || {});
                    td1.textContent = String(content || '');
                    td2.textContent = JSON.stringify(metadata || {});
                    tr.appendChild(td1); tr.appendChild(td2); body.appendChild(tr);
                });
                if ((!Array.isArray(list)) || list.length === 0) {
                    const tr = document.createElement('tr');
                    const td = document.createElement('td'); td.colSpan = 2; td.textContent = text && text.trim() ? text : '无结果';
                    tr.appendChild(td); body.appendChild(tr);
                }
            }catch(e){
                const tr = document.createElement('tr');
                const td = document.createElement('td'); td.colSpan = 2; td.textContent = '请求错误：' + e.message; tr.appendChild(td); document.getElementById('resultBody').appendChild(tr);
            }
        });
    </script>
</body>
</html>

